package com.msgqer.rchat.server;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

import com.msgqer.rchat.client.Client;
import com.msgqer.rchat.client.ClientGenerator;
import com.msgqer.rchat.client.ClientManager;
import com.msgqer.rchat.event.CommunicationEventGenerator;
import com.msgqer.rchat.message.MessageDto;
import com.msgqer.rchat.message.SystemMessageFormatter;

/**
 * 服务端
 * 
 * @author keaizhuzhu@公众号：面试怪圈 ;官网地址：{@link http://www.mianshiguaiquan.com}
 *         这里有更多面试、技术、学习资料及源码等
 *
 */
@ServerEndpoint(value = "/websocket")
@Component
public class RChatSocketServer {


	/**
	 * 连接建立成功调用的方法
	 */
	@OnOpen
	public void onOpen(Session session) {

		// 为每一个链接初始化一个客户端对象
		Client client = ClientGenerator.gen(session);

		// 将客户端对象维护在客户端管理器中
		ClientManager.addClient(client);

		// 对客户端推送一条「文明聊天」的系统消息事件
		client.sendTo(client, CommunicationEventGenerator.genSystemMessage(SystemMessageFormatter.TIP));

		// 广播「加入群聊」事件通知给所有客户端：xxx加入群聊
		String joinMessage = String.format(SystemMessageFormatter.JOIN, client.getClientName());
		client.broadcast(CommunicationEventGenerator.genSystemMessage(joinMessage));

		// 广播「当前在线人数」事件给所有客户端
		client.broadcast(
				CommunicationEventGenerator.genOnlineMemberMessage(ClientManager.getConnectedClients().size()));
	}

	/**
	 * 连接关闭调用的方法
	 */
	@OnClose
	public void onClose(Session session) {

		// 根据会话的Id获取当前退出的客户端对象
		Client client = ClientManager.get(session.getId());
		if (client == null) {
			return;
		}
		System.out.println("close:" + client.getClientName());

		// 广播「退出群聊」事件通知给所有客户端：xxx退出群聊
		String joinMessage = String.format(SystemMessageFormatter.QUIT, client.getClientName());
		client.broadcast(CommunicationEventGenerator.genSystemMessage(joinMessage));

		// 从客户端管理器中移除客户端对象
		ClientManager.removeClient(client);

		// 广播「当前在线人数」事件给所有客户端
		client.broadcast(
				CommunicationEventGenerator.genOnlineMemberMessage(ClientManager.getConnectedClients().size()));

	}

	/**
	 * 收到客户端消息后调用的方法
	 *
	 * @param message 客户端发送过来的消息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		//  根据会话的Id获取当前退出的客户端对象
		Client client = ClientManager.get(session.getId());
		if (client == null) {
			return;
		}

		// 将接收的客户端消息广播给所有的客户端
		client.broadcast(CommunicationEventGenerator.genCommonMessage(MessageDto.newMessageDto(client, message)));
	}

	/**
	 * 发生错误时调用
	 *
	 */
	@OnError
	public void onError(Session session, Throwable error) {

	}

}
